package service

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"mojieshi/define"
	"mojieshi/models"
	"net/http"
	"strconv"
	"time"
)

type MRechargeOrderJson struct {
	ID         int     `gorm:"type:int(10); primaryKey" json:"id"`
	Aid        int     `gorm:"type:int(10);" json:"aid"`           //账户ID
	Mid        int     `gorm:"type:int(10);" json:"mid"`           //用户id
	Money      float64 `json:"money"`                              //充值金额
	Give       float64 `json:"give"`                               //赠送金额
	GiveScore  int     `gorm:"type:int(10);" json:"give_score"`    //赠送积分
	Ordernum   string  `gorm:"type:varchar(255);" json:"ordernum"` //订单号
	Status     int     `gorm:"type:int(10);" json:"status"`        //0未支付;1已支付,4关闭
	Payorderid int     `gorm:"type:int(10);" json:"payorderid"`    //订单支付表id
	Paytypeid  int     `gorm:"type:int(10);" json:"paytypeid"`     //支付方式 2余额支付 1微信支付
	Paytype    string  `gorm:"type:varchar(255);" json:"paytype"`  //支付方式文本
	Paynum     string  `gorm:"type:varchar(255);" json:"paynum"`   //支付单号
	Paytime    int     `gorm:"type:int(10);" json:"paytime"`       //支付时间
	Platform   string  `json:"platform"`                           //来源平台 mp公众号 wx微信小程序
	CreatedAt  int     `gorm:"type:int(10);" json:"created_at"`
	UpdatedAt  int     `gorm:"type:int(10);" json:"updated_at"`
}

// 充值余额
func AddRecharge(c *gin.Context) {
	var jsonData MRechargeOrderJson
	err := c.ShouldBindJSON(&jsonData)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10000,
			"msg":  err,
		})
		return
	}
	//生成订单号
	var reData models.MRechargeOrder
	newTime := time.Now().Unix()
	reData.Mid = jsonData.Mid
	reData.Aid = jsonData.Aid
	reData.Money = decimal.NewFromFloat(jsonData.Money)
	reData.Give = decimal.NewFromFloat(jsonData.Give)
	reData.GiveScore = jsonData.GiveScore
	reData.Paytypeid = jsonData.Paytypeid
	reData.Paytype = jsonData.Paytype
	reData.Platform = jsonData.Platform
	reData.Ordernum = strconv.FormatInt(newTime, 10) + define.RandomNum(4)
	reData.Status = 0
	reData.CreatedAt = int(newTime)

	//开启事务
	tx := models.DB.Begin()
	err = tx.Create(&reData).Error //写入充值记录
	if err != nil {
		define.Response.ResultFail(c, 10001, define.JsonDataX, "")
		tx.Rollback()
		return
	}
	fmt.Println(decimal.NewFromFloat(jsonData.Money))
	//定义支付表数据
	var payOrderData models.MPayOrder
	payOrderData.Aid = jsonData.Aid
	payOrderData.Mid = jsonData.Mid
	payOrderData.Type = 2
	payOrderData.Status = 0
	payOrderData.Bid = 0
	payOrderData.Createtime = int(newTime)
	payOrderData.Money = decimal.NewFromFloat(jsonData.Money)
	payOrderData.Orderid = reData.ID
	payOrderData.Ordernum = reData.Ordernum
	payOrderData.Paytypeid = jsonData.Paytypeid
	payOrderData.Platform = jsonData.Platform
	payOrderData.Paytype = jsonData.Paytype
	payOrderData.Title = "余额充值"
	err = tx.Create(&payOrderData).Error
	if err != nil {
		define.Response.ResultFail(c, 10001, define.JsonDataX, "")
		tx.Rollback()
		return
	}
	var editData = map[string]interface{}{
		"payorderid": payOrderData.Id,
	}
	err = tx.Model(new(models.MRechargeOrder)).Where("id=?", jsonData.ID).Updates(&editData).Error
	if err != nil {
		define.Response.ResultFail(c, 10001, define.JsonDataX, "")
		tx.Rollback()
		return
	}
	tx.Commit() //结束事务
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"data": map[string]interface{}{
			"orderid":    jsonData.ID,
			"ordernum":   jsonData.Ordernum,
			"payorderid": payOrderData.Id,
		},
	})
}

// 获取系统基本设置
func GetRecharge(c *gin.Context) {
	var jsonData Newdata
	err := c.ShouldBindJSON(&jsonData)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10000,
			"msg":  err,
		})
		return
	}
	var data models.MRechargeGiveSet
	err = models.DB.Model(new(models.MRechargeGiveSet)).Where("id=? AND status=?", jsonData.Id, 1).First(&data).Error
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10001,
			"msg":  err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"data": map[string]interface{}{
			"list": data,
		},
	})
}

// 余额支付
func RechargeEdit(c *gin.Context) {
	var jsonData OrderPayJson
	err := c.ShouldBindJSON(&jsonData)
	if err != nil {
		define.Response.ResultFail(c, 10000, define.JsonDataX, "")
		return
	}
	//查询支付表信息
	//获取支付表信息
	var orderInfo models.MPayOrder
	err = models.DB.Model(new(models.MPayOrder)).Where("id=?", jsonData.Payorderid).First(&orderInfo).Error
	if err != nil {
		define.Response.ResultFail(c, 10001, err.Error(), "")
		return
	}
	//查询当前余额是否足够
	var UserObj models.MMember
	err = models.DB.Model(new(models.MMember)).Where("id=?", orderInfo.Mid).First(&UserObj).Error
	if err != nil {
		define.Response.ResultFail(c, 10002, err.Error(), "")
		return
	}
	//获取当前时间戳，计算超超时
	now := time.Now().Unix()
	Cnow := int64(orderInfo.Createtime) + int64(60*15)
	//判断支付过期时间
	if now > Cnow {
		define.Response.ResultFail(c, 10003, "支付超时", "")
		return
	}
	//	判断支付状态
	if orderInfo.Status != 0 {
		define.Response.ResultFail(c, 10004, "该订单已无法支付", "")
		return
	}
	fmt.Println(orderInfo.Money.Float64())
	fmt.Println(UserObj.Money.Float64())
	//判断用户当前余额是否够支付
	if define.FloatDecimal(orderInfo.Money) > define.FloatDecimal(UserObj.Money) {
		define.Response.ResultFail(c, 10005, "余额不足", "")
		return
	}
	tx := models.DB.Begin()
	yyyy := time.Now().Format("20060102150405")
	//更新支付表状态
	tx.Model(&orderInfo).Where("id = ?", orderInfo.Id).Updates(&models.MPayOrder{
		Status:  1,
		Paytime: int(time.Now().Unix()),
		TradeNo: yyyy,
	})
	if err != nil {
		define.Response.ResultFail(c, 10006, define.JsonDataX, "")
		tx.Rollback()
		return
	}
	if orderInfo.Type == 1 { //更新服务下单状态
		err = FuWuDetails(tx, orderInfo, yyyy, time.Now().Unix())
		if err != nil {
			define.Response.ResultFail(c, 10007, define.JsonDataX, "")
			tx.Rollback()
			return
		}
	}
	//给用户减去余额
	//写入余额记录
	cur := models.MoneyEdit(tx, UserObj.ID, orderInfo.Money, orderInfo.Aid, "余额支付，订单号:"+orderInfo.Ordernum)
	if cur == 2 {
		define.Response.ResultFail(c, 10009, define.JsonDataX, "")
		tx.Rollback()
		return
	}
	tx.Commit()
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"data":    "成功",
	})
}

// 充值卡兑换
func RechargeExchange(c *gin.Context) {
	var jsonData models.MRechargeExchange
	err := c.ShouldBindJSON(&jsonData)
	if err != nil {
		define.Response.ResultFail(c, 10000, define.JsonData, "")
		return
	}
	var list []models.MRechargeExchange
	var count int64
	nowTime := int(time.Now().Unix())
	err = models.DB.Model(new(models.MRechargeExchange)).Where("status=? AND hexiao_code=? AND start_time<? AND end_time>?", 1, jsonData.HexiaoCode, nowTime, nowTime).Count(&count).Find(&list).Error
	if err != nil {
		define.Response.ResultFail(c, 10001, define.JsonDataX, "")
		return
	}
	//判断兑换码是否有效
	if count <= 0 {
		define.Response.ResultFail(c, 10002, "兑换码不正确或已过期，请仔细确认！", "")
		return
	}
	tx := models.DB.Begin() //开启事务
	//更改充值卡状态
	var ExChangeData = map[string]interface{}{
		"status":        2,
		"mid":           jsonData.Mid,
		"exchange_time": int(time.Now().Unix()),
	}
	err = tx.Model(new(models.MRechargeExchange)).Where("id=?", list[0].ID).Updates(&ExChangeData).Error
	if err != nil {
		define.Response.ResultFail(c, 10003, define.JsonDataX, "")
		tx.Rollback()
		return
	}
	//写入用户的余额以及余额记录
	Newmoney := define.AddDecimal(list[0].Money, list[0].Give) //充值金额+赠送金额
	cur := models.MoneyAdd(tx, jsonData.Mid, Newmoney, jsonData.Aid, "充值卡余额充值，卡号:"+list[0].CardNumber)
	if cur == 2 {
		define.Response.ResultFail(c, 10004, define.JsonDataX, "")
		tx.Rollback()
		return
	}
	//判断是否有积分赠送
	if list[0].GiveScore > 0 {
		cur = models.ScoreAdd(tx, jsonData.Mid, list[0].GiveScore, jsonData.Aid, "充值卡余额充值赠送积分，卡号:"+list[0].CardNumber)
		if cur == 2 {
			define.Response.ResultFail(c, 10005, define.JsonDataX, "")
			tx.Rollback()
			return
		}
	}
	//写入充值订单
	//生成订单号
	var reData models.MRechargeOrder
	newTime := time.Now().Unix()
	reData.Mid = jsonData.Mid
	reData.Aid = jsonData.Aid
	reData.Money = list[0].Money
	reData.Give = list[0].Give
	reData.GiveScore = list[0].GiveScore
	reData.Paytypeid = 0
	reData.Paytype = "充值卡兑换"
	reData.Platform = "小程序"
	reData.Ordernum = strconv.FormatInt(newTime, 10) + define.RandomNum(4)
	reData.Status = 1
	reData.CreatedAt = int(newTime)
	err = tx.Create(&reData).Error //写入充值订单
	if err != nil {
		define.Response.ResultFail(c, 10006, define.JsonDataX, "")
		tx.Rollback()
		return
	}
	tx.Commit()
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"data":    "成功",
	})
}

type NewRecharData struct {
	Aid          int `json:"aid"`
	Mid          int `json:"mid"`
	CreatedStart int `json:"created_start"` //开始时间
	CreatedEnd   int `json:"created_end"`   //结束时间
	Page         int `json:"page"`
	Limit        int `json:"limit"`
}

// 查询余额明细
func GetRechargeShow(c *gin.Context) {
	var jsonData NewRecharData
	err := c.ShouldBindJSON(&jsonData)
	if err != nil {
		define.Response.ResultFail(c, 10000, define.JsonData, "")
		return
	}
	var list []models.MMemberMoneylog
	var count int64
	if jsonData.Page == 0 {
		jsonData.Page = -1
	}
	if jsonData.Limit == 0 {
		jsonData.Limit = -1
	}
	offsetVal := (jsonData.Page - 1) * jsonData.Limit
	if jsonData.Page == -1 && jsonData.Limit == -1 {
		offsetVal = -1
	}
	tx := models.DB.Model(new(models.MMemberMoneylog)).Where("aid=? AND mid=?", jsonData.Aid, jsonData.Mid)

	if jsonData.CreatedStart > 0 {
		tx = tx.Where("createtime>?", jsonData.CreatedStart/1000)
	}
	if jsonData.CreatedEnd > 0 {
		tx = tx.Where("createtime<?", jsonData.CreatedEnd/1000)
	}
	tx = tx.Count(&count).Limit(jsonData.Limit).Offset(offsetVal).Order("id desc").Find(&list)
	if err != nil {
		define.Response.ResultFail(c, 10001, err.Error(), "")
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"data": map[string]interface{}{
			"list":  list,
			"count": count,
		},
	})
}
